#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
from ib.ext.Contract import Contract
from ib.opt import ibConnection, message
from time import sleep, localtime, strftime
import datetime
from ib.ext.Order import Order
from ib.ext.ComboLeg import ComboLeg
from ib.ext.ContractDetails import ContractDetails

conId = -1
nextOrderId = -1
startTime = ''

pricelist = []
acnt = [0.0, 0.0, 0.0]
stkPosition = {}
optPosition = {}
futPosition = {}
openOrder = {}
bid, ask, last = 0., 0., 0.
l2ask = [(0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0)]
l2bid = [(0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0)]


# might not be efficient
"""
class openOrder(object):
    # maintain a list of orders IB API generated.
    # this id is different with permId
    m_contract = Contract()
    m_status = ""
    m_filled = int()
    m_remaining = int()
    m_avgFillPrice = float()
    # reserve it for now
    #permId = 0
    #parentId = 0
    #lastFilledPrice = 0.0
    #clientId = 0

    def __init__(self):
        self.m_status = ""
        self.m_filled = 0
        self.m_remaining = 0
        self.m_avgFillPrice = 0.0

    def __eq__(self, p_other):
        if self is p_other:
            return True
        if p_other is None:
            return False
        l_theOther = p_other
        #if (self.m_permId == l_theOther.m_permId):
            #return True
        if (self.m_contract != l_theOther.m_contract):
            return False
        return True
"""

def make_openOrder(contract, status, filled, remaining, avgFillPrice):
    newopenOrder = openOrder()
    newopenOrder.m_contract = contract
    newopenOrder.m_status = status
    newopenOrder.m_filled = filled
    newopenOrder.m_remaining = remaining
    newopenOrder.m_avgFillPrice = avgFillPrice
    return newopenOrder

def moving_average(x, n, type='simple'):
    '''
    compute an n period moving average.
    type is 'simple' | 'exponential'

    '''
    x = np.asarray(x)
    if type=='simple':
        weights = np.ones(n)
    else:
        weights = np.exp(np.linspace(-1., 0., n))

    weights /= weights.sum()


    a =  np.convolve(x, weights, mode='full')[:len(x)]
    a[:n] = a[n]
    return a

def relative_strength(prices, n=14):
    '''
    compute the n period relative strength indicator
    http://stockcharts.com/school/doku.php?id=chart_school:glossary_r#relativestrengthindex
    http://www.investopedia.com/terms/r/rsi.asp
    '''

    deltas = np.diff(prices)
    seed = deltas[:n+1]
    # this will have an issue with down = 0
    up = seed[seed>=0].sum()/n
    down = -seed[seed<0].sum()/n
    rsi = np.zeros_like(prices)
    if down == 0:
        rsi[:n] = 100.
    else:
        rs = up/down
        rsi[:n] = 100. - 100./(1.+rs)

    for i in range(n, len(prices)):
        delta = deltas[i-1] # cause the diff is 1 shorter

        if delta>0:
            upval = delta
            downval = 0.
        else:
            upval = 0.
            downval = -delta

        up = (up*(n-1) + upval)/n
        down = (down*(n-1) + downval)/n

        if down == 0:
            rsi = 100.
        else:
            rs = up/down
            rsi[i] = 100. - 100./(1.+rs)

    return rsi

def moving_average_convergence(x, nslow=26, nfast=12):
    '''
    compute the MACD (Moving Average Convergence/Divergence) using a fast and slow exponential moving avg'
    return value is emaslow, emafast, macd which are len(x) arrays
    '''
    emaslow = moving_average(x, nslow, type='exponential')
    emafast = moving_average(x, nfast, type='exponential')
    return emaslow, emafast, emafast - emaslow

def watcher(msg):
    print msg
#
def NextValidIdHandler(msg):
    global nextOrderId
    nextOrderId = msg.orderId

def getCurrentTime(msg):
    global startTime
    # confirm: local time on machine or server time???
    time_s =  localtime(int(msg.time))
    #startTime = strftime(localtime(int(msg.time)), '%Y%m%d %H:%M')
    # compare with machine time
    startTime = str(time_s.tm_year) + str(time_s.tm_mon).zfill(2) + str(time_s.tm_mday).zfill(2) + ' '\
            + str(time_s.tm_hour).zfill(2) + ':' + str(time_s.tm_min).zfill(2) + ':' + str(time_s.tm_sec).zfill(2)
    currentTime = strftime("%Y%m%d %H:%M:%S", localtime())
    print startTime
    #print currentTime

def ContractDetailsHandler(msg):
    global contractDetails
    contractDetails = msg.contractDetails

def my_BidAsk(msg):
    if msg.field == 1:
        print '%s:%s: bid: %s' % (contractTuple[0], contractTuple[6], msg.price)
    elif msg.field == 2:
        print '%s:%s: ask: %s' % (contractTuple[0], contractTuple[6], msg.price)

def print_account():
    global acnt
    print 'BBC', acnt[0]
    print 'PNL', acnt[1]
    print 'BP', acnt[2]

def update_account(msg):
    global acnt
    if msg.key == 'NetLiquidationByCurrency' and msg.currency == 'BASE':
        acnt[0] = float(msg.value)
    if msg.key == 'UnrealizedPnL' and msg.currency == 'BASE':
        acnt[1] = float(msg.value)
    if msg.key == 'BuyingPower':
        acnt[2] = float(msg.value)

def update_port(msg):
    global stkPosition, optPosition
    if msg.contract.m_secType == 'STK':
        stkPosition[msg.contract.m_symbol] = (msg.position, msg.averageCost, msg.marketPrice, msg.unrealizedPNL)
    if msg.contract.m_secType == 'OPT':
        optPosition[(msg.contract.m_symbol, msg.contract.m_right, msg.contract.m_expiry, msg.contract.m_strike)] = (msg.position, msg.averageCost, msg.marketPrice, msg.unrealizedPNL)
    if msg.contract.m_secType == 'FUT':
        futPosition[(msg.contract.m_symbol, msg.contract.m_expiry)] = (msg.position, msg.averageCost, msg.marketPrice, msg.unrealizedPNL)

def update_openOrder(msg):
    global openOrder, nextOrderId
    if len(openOrder) > 0:
        if msg.status == 'Filled':
            protected_t = openOrder[msg.orderId][6]
            if not protected_t:
                status_t = msg.status
                filled_t = msg.filled
                remaining_t = msg.remaining
                avgFillPrice_t = msg.avgFillPrice
                #print openOrder
                contract_t = openOrder[msg.orderId][0]
                #print contract
                #print msg.orderId
                openOrder[msg.orderId][1] = status_t
                openOrder[msg.orderId][2] = filled_t
                openOrder[msg.orderId][3] = remaining_t
                openOrder[msg.orderId][4] = avgFillPrice_t
                if openOrder[msg.orderId][5] == 'Sell':
                    order_t = 'Buy'
                    price_t = avgFillPrice_t + 2.25
                    trailStopPrice_t = avgFillPrice_t + 2.0
                    auxPrice_t = 2.0
                    #order_t = makeOrder(order_t, 'TRAILLIMIT', filled_t, price_t, trailStopPrice_t, auxPrice_t)
                    #con.placeOrder(nextOrderId, contract_t, order_t)
                    #openOrder[msg.orderId][6] = True
                    # the order status will be repeated three times, sleep one second to avoid multiple submittion
                    #nextOrderId = nextOrderId + 1
                if openOrder[msg.orderId][5] == 'Buy':
                    order_t = 'Sell'
                    price_t = avgFillPrice_t - 2.25
                    trailStopPrice_t = avgFillPrice_t - 2.0
                    auxPrice_t = 2.0
                    #order_t = makeOrder(order_t, 'TRAILLIMIT', filled_t, price_t, trailStopPrice_t, auxPrice_t)
                    #con.placeOrder(nextOrderId, contract_t, order_t)
                    #openOrder[msg.orderId][6] = True
                    #nextOrderId = nextOrderId + 1
    """
    #print openOrder
    status_t = msg.status
    filled_t = msg.filled
    remaining_t = msg.remaining
    avgFillPrice_t = msg.avgFillPrice
    #print openOrder
    #contract = openOrder[msg.orderId][0]
    #print contract
    #print msg.orderId
    openOrder[msg.orderId][1] = status_t
    openOrder[msg.orderId][2] = filled_t
    openOrder[msg.orderId][3] = remaining_t
    openOrder[msg.orderId][4] = avgFillPrice_t
    """

def updateMktDepth(msg):
    global l2ask, l2bid
    if msg.side == 0:
        l2ask[msg.position] = (msg.price, msg.size)
    if msg.side == 1:
        l2bid[msg.position] = (msg.price, msg.size)

def printMktDepth():
    global l2ask, l2bid
    for i in range(10):
        print '%.2f -- %d' % (l2ask[9-i][0], l2ask[9-i][1])

    print "---------------"

    for i in range(10):
        print '%.2f -- %d' % (l2bid[i][0], l2bid[i][1])

def print_port():
    global stkPosition, optPosition, futPosition
    print "\nStock Positions are: "
    for con, pos in stkPosition.iteritems():
        print con, pos[0], pos[1], pos[2], pos[3]

    print "\nOptions Positions are: "
    for con, pos in optPosition.iteritems():
        print con, pos[0], pos[1], pos[2], pos[3]

    print "\nFutures Positions are: "
    for con, pos in futPosition.iteritems():
        print con, pos[0], pos[1], pos[2], pos[3]

    """
    if msg.contract.m_secType == 'OPT':
        print msg.contract.m_conId, msg.contract.m_symbol, msg.contract.m_right, msg.contract.m_expiry, msg.contract.m_strike, msg.contract.m_right, msg.position, msg.unrealizedPNL
    if msg.contract.m_secType == 'STK':
        print msg.contract.m_conId, msg.contract.m_symbol, msg.position, msg.unrealizedPNL
    """
    #_con.register(watcher)
    #_con.reqContractDetails()

def print_openOrder():
    global openOrder
    print "\nOpen Orders are: "
    for con, order_s in openOrder.iteritems():
        print con, order_s[0], order_s[1], order_s[2], order_s[3], order_s[4]

def print_price(msg):
    #global pricelist
    if msg.field == 4:
        print msg.price
        #pricelist.append(msg.price)
        #sleep(1)

def print_option_chain(msg):
    print '%s, %s, %s, %s' % (msg.contractDetails.m_summary.m_conId, msg.contractDetails.m_summary.m_right, msg.contractDetails.m_summary.m_strike, msg.contractDetails.m_summary.m_expiry)

def get_realtimebar(msg):
    global pricelist
    print '%s, %f' % (msg.time, msg.wap)
    pricelist.append(msg.wap)

def makeStkContract(sym):
    newStkContract = Contract()
    newStkContract.m_symbol = sym
    newStkContract.m_secType = 'STK'
    newStkContract.m_strike = 0.00
    newStkContract.m_exchange = 'SMART'
    newStkContract.m_currency = 'USD'
    return newStkContract

def makeOptContract(_optStr):
    newContract = Contract()
    #_opt = _optStr.split(' ')
    newContract.m_symbol = _optStr
    newContract.m_secType = 'OPT'
    newContract.m_exchange = 'SMART'
    newContract.m_currency = 'USD'
    #newContract.m_expiry = _opt[1]
    #newContract.m_strike = _opt[2][1:]
    #newContract.m_right = _opt[2][0]
    return newContract

def makeOptContract2(_optStr):
    newContract = Contract()
    _opt = _optStr.split(' ')
    newContract.m_symbol = _opt[0]
    newContract.m_secType = 'OPT'
    newContract.m_exchange = 'SMART'
    newContract.m_currency = 'USD'
    newContract.m_expiry = _opt[1]
    newContract.m_strike = _opt[2][1:]
    newContract.m_right = _opt[2][0]
    return newContract

def makeFutContract(symbol, exchange, expiry):
    newContract = Contract()
    newContract.m_symbol = symbol
    newContract.m_secType = 'FUT'
    newContract.m_exchange = exchange
    newContract.m_currency = 'USD'
    newContract.m_expiry = expiry
    #newContract.m_strike = ''
    #newContract.m_right = ''
    return newContract

def printOptQuote(msg):
    bid, ask, last = 0., 0., 0.
    if msg.field == 1:
        bid = msg.price
    if msg.field == 2:
        ask = msg.price
    if msg.field == 4:
        last = msg.price
    print '%.2f, %.2f %.2f' % (bid, ask, last)

def printFutQuote(msg):
    if msg.field == 1:
        #print '%s:%s:bid: %s' % (contractTuple[0], contractTuple[6], msg.price)
        print 'bid: %s' % (msg.price)
    elif msg.field == 2:
        #print '%s:%s:ask: %s' % (contractTuple[0], contractTuple[6], msg.price)
        print 'ask: %s' % (msg.price)
    elif msg.field == 4:
        #print '%s:%s:last: %s' % (contractTuple[0], contractTuple[6], msg.price)
        print 'last: %s' % (msg.price)
    elif msg.field == 22:
        print 'open interest: %s' % msg

def makeStkOrder(action, orderID, orderType):
    newOptOrder = Order()
    newOptOrder.m_orderId = orderID
    newOptOrder.m_clientId = 0
    newOptOrder.m_permid = 0
    newOptOrder.m_action = action
    newOptOrder.m_lmtPrice = 0
    newOptOrder.m_auxPrice = 0
    newOptOrder.m_tif = 'DAY'
    newOptOrder.m_transmit = False
    newOptOrder.m_orderType = 'MKT'
    newOptOrder.m_totalQuantity = 100
    return newOptOrder

def makeOptOrder(orderID, action, lmtprice, quantity=2):
    newStkOrder = Order()
    newStkOrder.m_orderId = orderID
    newStkOrder.m_cliendId = 0
    newStkOrder.m_permid = 0
    newStkOrder.m_action = action
    newStkOrder.m_lmtPrice = lmtprice
    newStkOrder.m_tif = 'DAY'
    newStkOrder.m_transmit = True
    newStkOrder.m_orderType = 'LMT'
    newStkOrder.m_totalQuantity = quantity
    return newStkOrder

def makeOptLeg(conId, action):
    newComboLeg = ComboLeg()
    newComboLeg.m_conId = conId
    newComboLeg.m_ratio = 1
    newComboLeg.m_action = action
    newComboLeg.m_exchange = 'SMART'
    newComboLeg.m_openClose = 0
    newComboLeg.m_shortSaleSlot = 0
    newComboLeg.m_destinatedLocation = ''
    return newComboLeg

def makeBagContract(sym, legs):
    newBagContract = Contract()
    newBagContract.m_symbol = sym
    newBagContract.m_secType = 'BAG'
    newBagContract.m_exchange = 'SMART'
    newBagContract.m_currency = 'USD'
    newBagContract.m_comboLegs = legs
    return newBagContract

def makeOrder(action, tp, qty, price, trailStopPrice = 0.0, auxPrice = 0.0):
    newOrder = Order()
    newOrder.m_orderId = NextValidIdHandler
    newOrder.m_action = action
    newOrder.m_totalQuantity = qty
    newOrder.m_orderType = tp
    newOrder.m_lmtPrice = price
    newOrder.m_auxPrice = 0
    newOrder.m_tif = 'DAY'
    newOrder.m_trailStopPrice = trailStopPrice
    newOrder.m_auxPrice = auxPrice
    newOrder.m_triggerMethod = 0
    newOrder.m_outsideRth = True
    #newOrder.m_parentId = 0
    #newOrder.m_discretionaryAmt = 0.
    newOrder.m_transmit = True
    return newOrder

def getNextValidOrderId(msg):
    global orderId
    orderId = msg.orderId
    #orderId = orderId + 1

def getConId(contract):
    global contractDetails
    # reserve reqId = 9 for contract Id
    con.reqContractDetails(9, contract)
    #con.reqContractDetails(contract)
    # wait for TWS message to come back to message handler
    contractDetails = ContractDetails()
    while contractDetails.m_summary.m_conId == 0:
        sleep(1)

    return contractDetails.m_summary.m_conId

def print_open_order(msg):
    #if msg.key == 'OpenOrder':
        #print '%s,%s,%s,%s,%s -- %s' % (msg.orderId, msg.contract.m_symbol, msg.contract.m_expiry,\
            #msg.contract.m_right, msg.contract.m_strike, msg.orderState.m_status)
    #print '%s,%s,%s,%s,%s -- %s' % (msg.orderId, msg.contract.m_symbol, msg.contract.m_expiry,\
            #msg.contract.m_right, msg.contract.m_strike, msg.orderState.m_status)
    print msg

def buytest(msg):
    global nextOrderId
    if str(msg.time)[len(str(msg.time))-1] == '0':
        optOrder = makeOrder('BUY', 'MKT', 1, 0.0)
        con.placeOrder(nextOrderId, futContract, optOrder)
        nextOrderId = nextOrderId + 1
    else:
        optOrder = makeOrder('SELL', 'MKT', 1, 0.0)
        con.placeOrder(nextOrderId, futContract, optOrder)
        nextOrderId = nextOrderId + 1
    #print int(msg.time)

if __name__ == '__main__':
    #global stkPosition, optPosition, futPosition
    con = ibConnection()
    #con.host = '69.120.101.173'
    #con.host = '127.0.0.1'
    con.host = '69.120.108.218'
    con.port = 168
    #con.register(NextValidIdHandler, 'NextValidId')
    con.register(NextValidIdHandler, message.NextValidId)
    con.register(getNextValidOrderId, message)
    con.register(ContractDetailsHandler, 'ContractDetails')
    con.connect()

    con.setServerLogLevel(5)

    #account = 'aripp268'
    account = 'aripp004'
    tickId = 10
    reqId = 10
    reqIdHistoricalData0 = 0
    reqIdHistoricalData1 = 1
    reqIdHistoricalData2 = 2
    reqIdHistoricalData3 = 3
    reqIdHistoricalData4 = 4

    reqIdRealTimeBars = 2
    con.register(update_port, message.UpdatePortfolio)
    #futContract = makeFutContract('ES', 'GLOBEX', '20110617')
    #con.register(printFutQuote, message.TickPrice)
    #con.registerAll(watcher)
    #con.reqMktData(tickId, futContract, '', False)
    ESM1 = makeFutContract('ES', 'GLOBEX', '20110617')
    futContract = ESM1

    # request Historical Bar Data
    #con.reqHistoricalData(reqIdHistoricalData0, futContract, startTime, '1 D', '1 min', 'TRADES', 0, 1)
    #con.reqHistoricalData(reqIdHistoricalData1, futContract, startTime, '1 D', '5 mins', 'TRADES', 0, 1)
    #con.reqHistoricalData(reqIdHistoricalData2, futContract, startTime, '2 D', '15 mins', 'TRADES', 0, 1)
    #con.reqHistoricalData(reqIdHistoricalData3, futContract, startTime, '10 D', '1 hour', 'TRADES', 0, 1)
    #con.reqHistoricalData(reqIdHistoricalData4, futContract, startTime, '30 D', '1 day', 'TRADES', 0, 1)

    #con.cancelHistoricalData(tickId)
    #tickId = tickId + 1

    # request Current Time
    #con.register(getCurrentTime, message.CurrentTime)
    #con.reqCurrentTime()
    #tickId = tickId + 1

    # request RealTime Bars Data
    #con.register(buytest, message.RealtimeBar)
    #con.reqRealTimeBars(reqIdRealTimeBars, futContract, 5, 'TRADES', 0)

    # request Level 2 Market Data
    l2numRows = 25
    #con.register(updateMktDepth, message.UpdateMktDepth)
    #con.reqMktDepth(tickId, futContract, l2numRows)
    #tickId = tickId + 1
    con.register(update_openOrder, message.OrderStatus)
    con.register(update_port, message.UpdatePortfolio)
    con.register(update_account, message.UpdateAccountValue)
    con.reqAccountUpdates(1, account)
    #tickId = tickId + 1
    #con.reqAccountUpdates(tickId, account)

    while True:
        command = raw_input('\n>>command:')

        if command == 'acount' or command == 'a':
            #con.register(update_account, message.UpdateAccountValue)
            # tickId 1 reserved for Account Updates
            #con.reqAccountUpdates(1, account)
            #tickId = tickId + 1
            print_account()
            sleep(1)
            #con.unregisterAll(print_account)

        if command == 'port' or command == 'p':
            #reqId = 1
            ##con.register(update_port, message.UpdatePortfolio)
            #con.reqAccountUpdates(1, account)
            #tickId = tickId + 1
            print_port()
            sleep(1)
            #print message.items()
            #print message.UpdateAccountValue
            #print message.UpdateAccountValue.value
            #print len(message.UpdateAccountValue.value)

        if command == 'es':
            #ESM1 = makeFutContract('ES', 'GLOBEX', '20110617')
            #futContract = ESM1
            #con.register(printFutQuote, message.TickPrice)
            #con.register(watcher, message)
            #con.reqMktData(tickId, futContract, '', False)
            #tickId = tickId + 1

            # quote?
            #while True:
                #if raw_input("\n") != 'o':
                #con.register(printFutQuote, message.TickPrice)
                #con.reqMktData(tickId, futContract, '', False)
                    #con.register(printMktDepth, message)
                    #printMktDepth()
                    #sleep(0.5)
                #else:
                    #break

            #con.unregisterAll(printFutQuote)
            orderDetails = raw_input("Order Details:\n")
            details = orderDetails.split(" ")

            if len(details) == 3:
                order_t = details[0]
                size_lmt = details[1]
                price_lmt = float(details[2])
                futOrder = makeOrder(details[0], 'LMT', size_lmt, price_lmt)
                con.placeOrder(nextOrderId, futContract, futOrder)
                openOrder[nextOrderId] = [futContract, 'Submitted', 0, size_lmt, price_lmt, order_t, False]
                nextOrderId = nextOrderId + 1

            elif len(details) == 2:
                order_t = details[0]
                size_lmt = 1
                price_lmt = float(details[1])
                futOrder = makeOrder(order_t, 'LMT', size_lmt, price_lmt)
                con.placeOrder(nextOrderId, futContract, futOrder)
                openOrder[nextOrderId] = [futContract, 'Submitted', 0, size_lmt, price_lmt, order_t, False]
                nextOrderId = nextOrderId + 1

            elif len(details) == 1 and details[0] not in ['liquid', 'l']:
                order_t = ''
                if details[0] == 'B' or details[0] == 'Buy' or details[0] == 'b' or details[0] == 'buy':
                    order_t = 'Buy'
                elif details[0] == 'S' or details[0] == 'Sell' or details[0] == 's' or details[0] == 'sell':
                    order_t = 'Sell'

                size_mkt = 1
                # To record current market price
                price_mkt = 0.0
                futOrder = makeOrder(order_t, 'MKT', 1, 0.0)
                con.placeOrder(nextOrderId, futContract, futOrder)
                openOrder[nextOrderId] = [futContract, 'Submitted', 0, size_mkt, price_mkt, order_t, False]
                nextOrderId = nextOrderId + 1

            # liquidation uses market order, there should not be any issue, no tracking for now
            elif details[0] == 'liquid' or details[0] == 'l':
                for ctrt, pos in futPosition.iteritems():
                    if ctrt[0] == 'ES':
                        size_r = pos[0]
                        if size_r > 0:
                            futOrder = makeOrder('SELL', 'MKT', size_r, 0)
                            con.placeOrder(nextOrderId, futContract, futOrder)
                            openOrder[nextOrderId] = [futContract, 'Submitted', 0, size_r, 0, 'Sell', False]
                            nextOrderId = nextOrderId + 1
                        if size_r < 0:
                            futOrder = makeOrder('BUY', 'MKT', -size_r, 0)
                            con.placeOrder(nextOrderId, futContract, futOrder)
                            openOrder[nextOrderId] = [futContract, 'Submitted', 0, -size_r, 0, 'Buy', False]
                            nextOrderId = nextOrderId + 1
            #printMktDepth()
            #print '\n ------------------------------ \n'
            sleep(1)

        if command == 'order status' or command == 'os':
            #con.register(print_open_order, message.OpenOrder)
            #con.reqOpenOrders()
            print_openOrder()
            sleep(1)

        if command == 'exit' or command == 'quit' or command == 'q':
            con.disconnect()
            break;

        else:
            continue
    #con.isConnected()

    """
    while True:
        command = raw_input('\n>>command:')
        con.unregisterAll(print_port)
        con.unregisterAll(print_account)
        con.unregisterAll(print_open_order)
        #con.register(print_open_order, message.OpenOrder)
        #con.register(update_port, message.UpdatePortfolio)
        #con.reqAccountUpdates(tickId, account)

        if command == 'acount' or command == 'a':
            con.register(print_account, message.UpdateAccountValue)
            con.reqAccountUpdates(tickId, account)
            sleep(1)

        if command == 'port' or command == 'p':
            #reqId = 1
            #con.register(update_port, message.UpdatePortfolio)
            #con.reqAccountUpdates(tickId, account)
            sleep(1)
            print_port()
            #print message.items()
            #print message.UpdateAccountValue
            #print message.UpdateAccountValue.value
            #print len(message.UpdateAccountValue.value)

        if command == 'liquid' or command == 'l':
            #con.register(print_port, message.UpdatePortfolio)
            #con.reqAccountUpdates(tickId, account)
            sleep(1)
            print 'which one you want to liquid?'
            contract = raw_input('stock or option or combo?\n')
            if contract == 'stock' or 'S':

        if command == 'options order' or command == 'oo':
            opt = raw_input("Symbol:\n")
            #opt = 'GS 20101217 C160'
            optContract = makeOptContract2(opt)
            while raw_input("Quote:\n") != 'n':
                con.register(printOptQuote, message.TickPrice)
                con.reqMktData(tickId, optContract, '', False)
            con.unregisterAll(printOptQuote)

            orderDetails = raw_input("Order Details:\n")
            details = orderDetails.split(" ")
            if len(details) == 3:
                optOrder = makeOrder(details[0], 'LMT', int(details[1]), float(details[2]))
            elif len(details) == 2:
                optOrder = makeOrder(details[0], 'LMT', 2, float(details[1]))
                con.placeOrder(nextOrderId, optContract, optOrder)
            sleep(1)

        futContract = makeESContract('20110617')
        #con.register(printFutQuote, message.TickPrice)
        con.register(watcher, message)
        con.reqMktData(tickId, futContract, '', False)


            if len(details) == 3:
                futOrder = makeOrder(details[0], 'LMT', details[1], float(details[2]))
                con.placeOrder(nextOrderId, futContract, futOrder)

            elif len(details) == 2:
                futOrder = makeOrder(details[0], 'LMT', 1, float(details[1]))
                con.placeOrder(nextOrderId, futContract, futOrder)

            elif details[0] == "liquid":
                for ctrt, pos in futPosition.iteritems():
                    if ctrt[0] == 'ES':
                        if pos[0] > 0:
                            futContract = makeESContract(ctrt[1])
                            futOrder = makeOrder('SELL', 'MKT', pos[0], 0)
                            con.placeOrder(nextOrderId, futContract, futOrder)
                        if pos[0] < 0:
                            futContract = makeESContract(ctrt[1])
                            futOrder = makeOrder('BUY', 'MKT', -pos[0], 0)
                            con.placeOrder(nextOrderId, futContract, futOrder)
            sleep(1)

        if command == 'combo order' or command == 'co':
            opt1 = raw_input("Short Symbol:\n")
            opt2 = raw_input("Long Symbol:\n")
            #opt1 = 'GS 20101217 P160'
            #opt2 = 'GS 20101217 P165'
            optContract1 = makeOptContract2(opt1)
            optContract2 = makeOptContract2(opt2)

            conId1 = getConId(optContract1)
            conId2 = getConId(optContract2)

            shortLeg = makeOptLeg(conId1, 'SELL')
            longLeg = makeOptLeg(conId2, 'BUY')
            bagContract = makeBagContract('GS', [shortLeg, longLeg])
            orderDetails = raw_input("Order Details:\n")
            details = orderDetails.split(" ")
            if len(details) == 3:
                optOrder = makeOrder(details[0], 'LMT', int(details[1]), float(details[2]))
            else:
                optOrder = makeOrder(details[0], 'LMT', 2, float(details[1]))
            #buyOrder = makeOrder('BUY', 2, 0.02)
            con.placeOrder(nextOrderId, bagContract, buyOrder)
            sleep(1)

        if command == 'option chain' or command == 'oc':
            reqId = 2
            sym = raw_input('Please input the symbol: ')
            optContract = makeOptContract(sym)
            con.register(print_option_chain, message.ContractDetails)
            con.reqContractDetails(reqId, optContract)
            sleep(5)
            con.unregister(print_option_chain, message.ContractDetails)

        if command == 'order status' or command == 'os':
            con.register(print_open_order, message.OpenOrder)
            con.reqOpenOrders()
            sleep(1)

        if command == 'exit' or command == 'quit' or command == 'q':
            con.disconnect()
            break;

        else:
            continue

        #con.reqAccountUpdates(tickId,'aripp268')
        #tickId = tickId + 1
        #con.reqManagedAccts()
        #con.reqAllOpenOrders()
        #con.placeOrder(tickId, stkContract, stkOrder)
        #stkContract.m_orderType = 'MKT'
        #stkContract.m_totalQuantity = 50
        #tickId = tickId + 1
        #contractTuple2 = ('AMZN', 'STK', 'SMART', 'USD', '', 0.0, '')
        #stkContract2 = makeStkContract(contractTuple2)
        #stkOrder2 = makeStkOrder('SELL', orderId, 'GTC', 'MKT', 157.40, 100)
        #con.placeOrder(tickId, stkContract2, stkOrder2)
        ##con.reqRealTimeBars(tickId, stkContract, '1 S', 'TRADES', 1)
        #sleep(1000)
        """
    con.disconnect()
    #sleep(1)
